package sv.gob.mh.dgii.jasper.service;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import sv.gob.mh.dgii.jasper.ReportData;
import sv.gob.mh.dgii.jasper.Reporte;

@Service
public class ReportingService {

    private final static String FILE_SEPARATOR = File.separator;
    @Autowired
    @Qualifier("dataSourceReports")
    private DataSource dataSourceReports;
    private static Connection connection;
    private final static Log log = LogFactory.getLog(ReportingService.class);

    public final Connection getConnection() {
        try {
            if (connection == null) {
                connection = dataSourceReports.getConnection();
            }
        } catch (Exception ex) {
            log.fatal(ex);
        }
        return connection;
    }

    public void executeReport(HttpServletRequest request, HttpServletResponse response) {
        try {
            Reporte reporte = initParams(request, response);
            if (reporte != null) {
                if (reporte.getReportData().isUsingConneciton()) {
                    reporte.setConexionJDBC(getConnection());
                }
                reporte.executeReport(request, response);
                reporte.executeAfterReport(request, response);
                reporte.closeAll();
            } else {
                throw new RuntimeException("No se pudieron cargar los parametros del reporte.");
            }
        } catch (Exception e) {
            try {
                response.sendError(404, e.getMessage());
            } catch (Exception ex) {
                log.error(ex);
            }
            throw new RuntimeException(e);
        }
    }

    protected Reporte initParams(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Reporte reporte = null;
        try {
            ReportData data = Reporte.getReportInSession(request.getSession(), request.getParameter("reportName"));
            if (data != null) {
                reporte = new Reporte();
                reporte.setReportData(data);
                String contextPath = request.getSession().getServletContext().getRealPath("");
                reporte.executeBeforeReport(request, response);
                if (reporte.getReportData().getRutaImagenes() == null || (reporte.getReportData().getRutaImagenes() != null && "".equals(reporte.getReportData().getRutaImagenes()))) {
                    reporte.getReportData().setRutaImagenes(contextPath + FILE_SEPARATOR + "images");
                }
                if (reporte.getReportData().getRutaReportes() == null || (reporte.getReportData().getRutaReportes() != null && "".equals(reporte.getReportData().getRutaReportes()))) {
                    reporte.getReportData().setRutaReportes(contextPath + FILE_SEPARATOR + "WEB-INF" + FILE_SEPARATOR + "reports");
                }
                if (reporte.getReportData().getRutaSubreporte() == null || (reporte.getReportData().getRutaSubreporte() != null && "".equals(reporte.getReportData().getRutaSubreporte()))) {
                    reporte.getReportData().setRutaSubreporte(reporte.getReportData().getRutaReportes() + FILE_SEPARATOR + reporte.getReportData().getModulo() + FILE_SEPARATOR);
                }
                if (reporte.getReportData().getNumeroMaximoRegistros() <= 0) {
                    reporte.getReportData().setNumeroMaximoRegistros(Reporte.MAX_NUM_ROWS_PER_REPORT);
                }
                log.debug("trying to execute report:" + reporte.getReportData().getNombreArchivo() + "-" + reporte);
            } else {
                throw new RuntimeException("No se encuentra en sesion el reporte \"" + request.getParameter("reportName") + "\"");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return reporte;
    }
}
